package epibot.WebRobots;

import epibot.EstruturasBiologicas.Epitopo;
import epibot.EstruturasBiologicas.Proteina;
import epibot.robot.Proxy.GereciadorDoProxy;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

/**
 * http://www.imtech.res.in/raghava/nhlapred/comp.html
 *
 * Query to the nHLAPred with ANNPred algorithm
 */
public class Bimas {
    
    public static Proteina processCalibragem(String seq, String allele, String epi_len,
            String codProteina, String nomeSite) throws IOException {
        String rline; // Represents a line of the result table

        //criei a proteina
        Proteina p = new Proteina(codProteina, nomeSite, allele, epi_len, 0); // só para armazenar a proteina e os epítopos

        // build the URL and POST
        URL url = new URL("http://www-bimas.cit.nih.gov/cgi-bin/molbio/ken_parker_comboform");
        //URLConnection http = url.openConnection();

        URLConnection http;
        Proxy proxy = GereciadorDoProxy.getConexao();

        if (proxy == null) {
            //System.out.println("sem proxy");
            http = url.openConnection();
        } else {
            // System.out.println("com proxy");
            http = url.openConnection(proxy);
        }

        http.setDoOutput(true);
        OutputStream os = null;
        try {
            os = http.getOutputStream();
        } catch (UnknownHostException ex) {
            //  System.out.println("proxy errado");
            return null;
        }

        String a = "";

        if (allele.equals("H2-Kd")) {
            a = "Kd";
        }
        if (allele.equals("H2-Kb")) {
            a = "Kb";
        }
        if (allele.equals("H2-Kk")) {
            a = "Kk";
        }
        if (allele.equals("HLA-A0201")
                || allele.equals("HLA-A1101")
                || allele.equals("HLA-B2705")
                || allele.equals("HLA-B3801")
                || allele.equals("HLA-B3901")
                || allele.equals("HLA-B3902")
                || allele.equals("HLA-B5101")
                || allele.equals("HLA-A0205")
                || allele.equals("HLA-A3101")
                || allele.equals("HLA-B2702")
                || allele.equals("HLA-B3501")
                || allele.equals("HLA-B3701")
                || allele.equals("HLA-B4403")
                || allele.equals("HLA-B5102")
                || allele.equals("HLA-B5103")
                || allele.equals("HLA-B5201")
                || allele.equals("HLA-B5801")) {
            a = allele.replace("HLA-", "");
            if (a.charAt(0) == 'A') {
                a = a.replace("A", "A_");
            } else {
                a = a.replace("B", "B_");
            }
        }

        // construct the form
        FormUtility form = new FormUtility(os, null);
        form.add("hla_molecule_type", a); //alterar como trata esse condicional
        form.add("subsequence_length", epi_len);
        form.add("result_limit_method", "explicit number");
        form.add("number_of_results_to_display", "250");
        form.add("cutoff_score", "100");
        form.add("inseq", seq);
        form.add("echo_inseq", "N");
        form.add("echo_format", "Numbered lines (useful)");
        form.add("program", "KenParker HTML Form .9beta");
        form.add("submit", "submit");

        // Submit form
        form.complete();

        // read the results an parse the table
        InputStream is = http.getInputStream();
        ParseHTML parse = new ParseHTML(is);
        StringBuilder buffer = new StringBuilder();
        List<String> list = new ArrayList<String>();
        boolean capture = false;

        // select the result table
        if (!advance(parse, "table", 2)) {
            return null;
        }

        int rank = 0;
        String scoreAnt = "";

        // Parse the table. Ignores the head lines.
       
        int ch;
        while ((ch = parse.read()) != -1) {
            if (ch == 0) {
                HTMLTag tag = parse.getTag();
                if (tag.getName().equalsIgnoreCase("tr")) {
                    list.clear();
                    capture = false;
                    buffer.setLength(0);
                } else if (tag.getName().equalsIgnoreCase("/tr")) {
                    /*
                     * Write each found epitop to the result file
                     */
                    if (list.size() > 0) {
                        // Discard the 2 initial lines
                        rline = processTableRow(list); // Extract the epitop from table line
                        //System.out.println(rline.substring(i+1,j+1) + rline.substring(0, i) + rline.substring(j));

                        // Reorder the protein and the position in the string
                        int i, j;
                        i = rline.indexOf(',');
                        j = rline.lastIndexOf(',');

                        String epitopo = rline.substring(i + 1, j);
                        String posicao = rline.substring(0, i);
                        String score = rline.substring(j + 1);

                        if (!score.equals(scoreAnt)) {
                            rank++;
                        }
                        scoreAnt = score;

                        
                        //acrescentar o rank do epitopo
                        //System.out.println(epitopo+","+posicao+","+score);                       
                        p.addEpitopo(new Epitopo(epitopo.toUpperCase(), Integer.parseInt(posicao), Double.parseDouble(score), rank, p));

                        list.clear();
                    }
                } else if (tag.getName().equalsIgnoreCase("td")) {
                    if (buffer.length() > 0) {
                        list.add(buffer.toString());
                    }
                    buffer.setLength(0);
                    capture = true;
                } else if (tag.getName().equalsIgnoreCase("/td")) {
                    list.add(buffer.toString());
                    buffer.setLength(0);
                    capture = false;
                } else if (tag.getName().equalsIgnoreCase("/table")) {
                    break;
                }
            } else {
                if (capture) {
                    buffer.append((char) ch);
                }
            }
        }
        is.close();
        
//        System.out.println(p.getListaDeEpitopos().size());
        return p;
    }// fim do m�todo process

    /**
     * Avancça para a tag HTML especificado.
     *
     * @param parse o objeto de análise HTML para usar.
     * @param tag A tag HTML.
     * @param count quantas etiquetas como esta para encontrar.
     *
     * @return True se encontrou, false caso contrário.
     * @throws IOException Se ocorrer uma exceção durante a leitura.
     */
    private static boolean advance(ParseHTML parse, String tag, int count)
            throws IOException {
        int ch;
        while ((ch = parse.read()) != -1) {
            if (ch == 0) {
                if (parse.getTag().getName().equalsIgnoreCase(tag)) {
                    count--;
                    if (count <= 0) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * Este método é chamado uma vez para cada linha da tabela localizado, ele
     * contém uma lista De todas as colunas dessa linha.
     *
     * @param list lista que foram encontrados nesta linha.
     *
     */
    private static String processTableRow(List<String> list) {
        int column_count = 1;
        StringBuilder result = new StringBuilder();

        for (String item : list) {
            // Do not pick the first two columns
            if (column_count > 1) {
                if (result.length() > 0) {
                    result.append(",");
                }
                result.append(item.trim());
            }
            column_count++;
        }
        return result.toString();
    }
}
